package com.h3c.ptability.controller;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.eos.common.constant.StatusCodeEnum;
import com.eos.common.custom.BusinessException;
import com.eos.common.util.DateUtils;
import com.eos.common.util.Result;
import com.google.common.base.Charsets;
import com.h3c.it.common.misc.lang.Assert;
import com.h3c.ptability.dto.ExcelFileDTO;
import com.h3c.ptability.dto.OptionsDTO;
import com.h3c.ptability.dto.PtDeptDTO;
import com.h3c.ptability.dto.PtUserDeptMonthDTO;
import com.h3c.ptability.entity.PtUserDeptMonth;
import com.h3c.ptability.mapper.PtUserDeptMonthMapper;
import com.h3c.ptability.service.IPtEnumService;
import com.h3c.ptability.service.IPtUserDeptMonthService;
import com.h3c.ptability.support.PageQuery;
import com.h3c.ptability.support.ResultData;
import com.h3c.ptability.task.ResetDynamicBoardHandler;
import com.h3c.ptability.task.ResetHrBudgetHandler;
import com.h3c.ptability.task.ResetHrLeaderHandler;
import com.h3c.ptability.utils.CommonUtil;
import com.h3c.ptability.vo.PtUserDeptMonthVO;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
import java.text.ParseException;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


/**
 * PtUserDeptMonth相关api接口
 *
 * @author h24002
 * @date 2022-10-27
 */
@Slf4j
@CrossOrigin
@RestController
@RequestMapping(value = "/ptUserDeptMonth")
public class PtUserDeptMonthController {

    @Resource
    private IPtUserDeptMonthService ptUserDeptMonthService;

    @Resource
    private IPtEnumService ptEnumService;

    @Resource
    private ResetHrBudgetHandler resetHrBudgetHandler;

    @Resource
    private ResetDynamicBoardHandler resetDynamicBoardHandler;

    @Resource
    private ResetHrLeaderHandler resetHrLeaderHandler;

    @Resource
    PtUserDeptMonthMapper deptMonthMapper;

    /**
     * 查询应用下当前部门下的部门集合
     *
     * @param dto 应用+日期+部门
     * @return 部门列表信息，含授权主管信息
     */
    @RequestMapping(value = "/queryChildrenDeptList", method = RequestMethod.POST)
    public Result queryChildrenDeptList(@RequestBody PtUserDeptMonthDTO dto) {
        Assert.notNull(dto, CommonUtil.errorMsg("空值传入"));
        ptUserDeptMonthService.checkOperationValid(dto.getAppId());
        //初始化部门编码
        if (dto.getDeptId() == null) {
            dto.setDeptId(50040000);
        }
        List<PtDeptDTO> ptDeptDTOS = ptUserDeptMonthService.queryChildrenDeptList(dto);
        return new Result(true, StatusCodeEnum.SEARCH_SUCCESS, ptDeptDTOS);
    }

    /**
     * 下载部门信息（授权用户）
     *
     * @param dto      应用+日期+部门
     * @param response 返回实体：部门列表信息，含授权主管信息
     */
    @RequestMapping(value = "/downloadDeptUserData", method = RequestMethod.POST)
    public void downloadDeptUserData(@RequestBody PtUserDeptMonthDTO dto,
                                     HttpServletResponse response) {
        try {
            Assert.notNull(dto, CommonUtil.errorMsg("空值传入"));
            ptUserDeptMonthService.checkOperationValid(dto.getAppId());
            List<PtDeptDTO> ptDeptDTOS = ptUserDeptMonthService.queryChildrenDeptList(dto);
            ExcelFileDTO excelFileDTO = new ExcelFileDTO();
            excelFileDTO.setAppId("ptability-manage");
            excelFileDTO.setDataList(ptDeptDTOS);
            excelFileDTO.setFileName(dto.getAppId() + "-月度部门授权用户信息表");
            excelFileDTO.setTemplateCode("PT_DEPT_EXPORT");
            File downLoadFile = ptEnumService.getExcelFile(excelFileDTO);
            FileInputStream inputStream = new FileInputStream(downLoadFile);
            byte[] buffer = new byte[(int) downLoadFile.length()];
            inputStream.read(buffer);
            inputStream.close();
            FileUtil.del(downLoadFile);
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding(Charsets.UTF_8.name());
            response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(downLoadFile.getName(), Charsets.UTF_8.name()));
            response.setHeader("issuccess", "1");
            response.setHeader("Access-Control-Expose-Headers", "Content-disposition,issuccess");
            IoUtil.write(response.getOutputStream(), true, buffer);
        } catch (IOException e) {
            log.error("导出excel报错,原因:{}{}", e.getMessage(), e.toString());
            throw new BusinessException(StatusCodeEnum.REQ_DOWNLOAD_FAIL);
        }
    }

    /**
     * 导入用户授权部门信息
     *
     * @param appId 应用编码
     * @param file  导入数据文件
     * @return 导入结果
     */
    @ApiImplicitParams({@ApiImplicitParam(name = "file", value = "导入数据文件", required = true, dataType = "MultipartFile", paramType = "body")})
    @RequestMapping(value = "/importDeptUserData", method = RequestMethod.POST)
    public ResultData importDeptUserData(@RequestParam(value = "appId") String appId,
                                         @RequestParam(value = "file") MultipartFile file) {
        Assert.hasText(appId, CommonUtil.errorMsg("空值传入"));
        ptUserDeptMonthService.checkOperationValid(appId);
        ptUserDeptMonthService.importDeptUserData(appId, file);
        return ResultData.success("导入成功");
    }

    /**
     * 查询用户授权的部门树(一二三级部门)
     *
     * @param dto 查询条件
     * @return 部门树结构
     */
    @PostMapping("/queryUserDeptMonthTree")
    public Result queryUserDeptMonthTree(@RequestBody PtUserDeptMonthDTO dto) {
        Assert.notNull(dto, CommonUtil.errorMsg("空值传入"));
        Assert.hasText(dto.getAppId(), CommonUtil.errorMsg("应用空值传入"));
        Assert.hasText(dto.getUserId(), CommonUtil.errorMsg("用户空值传入"));
        List<OptionsDTO> result = ptUserDeptMonthService.queryUserDeptMonthTree(dto);
        return new Result(true, StatusCodeEnum.SEARCH_SUCCESS, result);
    }

    /**
     * 查询部门树(一二三级部门)
     *
     * @param dto 查询条件
     * @return 部门树结构
     */
    @PostMapping("/queryDeptTreeSelection")
    public Result queryDeptTreeSelection(@RequestBody PtUserDeptMonthDTO dto) {
        Assert.hasText(dto.getAppId(), CommonUtil.errorMsg("空值传入"));
        ptUserDeptMonthService.checkOperationValid(dto.getAppId());
        List<OptionsDTO> result = ptUserDeptMonthService.queryDeptTreeSelection(dto);
        return new Result(true, StatusCodeEnum.SEARCH_SUCCESS, result);
    }

    /**
     * 分页查询
     *
     * @param pageQuery 查询条件
     * @return com.h3c.board.model.Result
     * @author h24002
     * @date 2022-10-27
     */
    @PostMapping("/page")
    public Result<Object> selectPage(@RequestBody PageQuery<PtUserDeptMonthDTO> pageQuery) {
        if (pageQuery.getCondition() == null) {
            pageQuery.setCondition(new PtUserDeptMonthDTO());
        }
        ptUserDeptMonthService.checkOperationValid(pageQuery.getCondition().getAppId());
        IPage<PtUserDeptMonthVO> pageInfo = ptUserDeptMonthService.selectPage(pageQuery);
        return new Result(true, StatusCodeEnum.SEARCH_SUCCESS, pageInfo);
    }

    /**
     * 添加数据
     *
     * @param dto 实体
     * @return com.h3c.board.model.Result
     * @author h24002
     * @date 2022-10-27
     */
    @PostMapping("insertDto")
    public Result<Object> insert(@RequestBody PtUserDeptMonthDTO dto) {
        Assert.notNull(dto, CommonUtil.errorMsg("空值传入"));
        Assert.notNull(dto.getDateId(), CommonUtil.errorMsg("操作日期不可为空"));
        ptUserDeptMonthService.checkOperationValid(dto.getAppId());
        ptUserDeptMonthService.insertDto(dto);
        return new Result(true, StatusCodeEnum.ADD_SUCCESS);
    }

    /**
     * 添加数据
     *
     * @param info 实体
     * @return com.h3c.board.model.Result
     * @author h24002
     * @date 2022-10-27
     */
    @PostMapping("insert")
    public Result<Object> insert(@RequestBody PtUserDeptMonth info) {
        Assert.notNull(info, CommonUtil.errorMsg("空值传入"));
        Assert.notNull(info.getDateId(), CommonUtil.errorMsg("操作日期不可为空"));
        ptUserDeptMonthService.checkOperationValid(info.getAppId());
        ptUserDeptMonthService.insert(info);
        return new Result(true, StatusCodeEnum.ADD_SUCCESS);
    }

    /**
     * 批量添加数据
     *
     * @param dtoList 实体
     * @return com.h3c.board.model.Result
     * @author h24002
     * @date 2022-10-27
     */
    @PostMapping("insertDtoList")
    public Result<Object> insertDtoList(@RequestBody List<PtUserDeptMonthDTO> dtoList) {
        Assert.notEmpty(dtoList, CommonUtil.errorMsg("空值传入"));
        List<String> appIdList = dtoList.stream().map(PtUserDeptMonthDTO::getAppId).distinct().collect(Collectors.toList());
        for (String appId : appIdList) {
            ptUserDeptMonthService.checkOperationValid(appId);
        }
        ptUserDeptMonthService.insertDtoList(dtoList);
        return new Result(true, StatusCodeEnum.ADD_SUCCESS);
    }

    /**
     * 批量添加数据
     *
     * @param list 实体
     * @return com.h3c.board.model.Result
     * @author h24002
     * @date 2022-10-27
     */
    @PostMapping("insertList")
    public Result<Object> insertList(@RequestBody List<PtUserDeptMonth> list) {
        Assert.notEmpty(list, CommonUtil.errorMsg("空值传入"));
        List<String> appIdList = list.stream().map(PtUserDeptMonth::getAppId).distinct().collect(Collectors.toList());
        for (String appId : appIdList) {
            ptUserDeptMonthService.checkOperationValid(appId);
        }
        ptUserDeptMonthService.insertList(list);
        return new Result(true, StatusCodeEnum.ADD_SUCCESS);
    }

    /**
     * 重置用户授权的部门数据
     *
     * @param dto 条件
     * @return com.h3c.board.model.Result
     * @author h24002
     * @date 2022-10-27
     */
    @PutMapping("/update")
    public Result<Object> update(@RequestBody PtUserDeptMonthDTO dto) {
        Assert.notNull(dto, CommonUtil.errorMsg("空值传入"));
        ptUserDeptMonthService.checkOperationValid(dto.getAppId());
        Assert.hasText(dto.getUserId(), CommonUtil.errorMsg("用户空值传入"));
        Assert.notEmpty(dto.getDeptIdList(), CommonUtil.errorMsg("部门空值传入"));
        dto.setDeptId(null);
        ptUserDeptMonthService.update(dto);
        return new Result(true, StatusCodeEnum.UPDATE_SUCCESS);
    }

    /**
     * 根据条件删除数据
     *
     * @param condition 条件
     * @return com.h3c.board.model.Result
     * @author h24002
     * @date 2022-10-27
     */
    @DeleteMapping("/delete")
    public Result<Object> delete(@RequestBody PtUserDeptMonthDTO condition) {
        Assert.notNull(condition, CommonUtil.errorMsg("空值传入"));
        ptUserDeptMonthService.checkOperationValid(condition.getAppId());
        ptUserDeptMonthService.delete(condition);
        return new Result(true, StatusCodeEnum.REMVOE_SUCCESS);
    }

    /**
     * 根据条件查询详情
     *
     * @param condition 条件
     * @return com.h3c.board.model.Result
     * @author h24002
     * @date 2022-10-27
     */
    @PostMapping("/selectOne")
    public Result<Object> selectOne(@RequestBody PtUserDeptMonthDTO condition) {
        Assert.notNull(condition, CommonUtil.errorMsg("空值传入"));
        ptUserDeptMonthService.checkOperationValid(condition.getAppId());
        List<PtUserDeptMonthVO> voList = ptUserDeptMonthService.select(condition);
        PtUserDeptMonthVO ptUserDeptMonthVO = voList.stream().findFirst().orElse(null);
        return new Result(true, StatusCodeEnum.SEARCH_SUCCESS, ptUserDeptMonthVO);
    }

    /**
     * 根据条件查询详情
     *
     * @param condition 条件
     * @return com.h3c.board.model.Result
     * @author h24002
     * @date 2022-10-27
     */
    @PostMapping("/select")
    public Result<Object> select(@RequestBody PtUserDeptMonthDTO condition) {
        Assert.notNull(condition, CommonUtil.errorMsg("空值传入"));
        List<PtUserDeptMonthVO> voList = ptUserDeptMonthService.select(condition);
        return new Result(true, StatusCodeEnum.SEARCH_SUCCESS, voList);
    }

    /**
     *  查询部门的某些角色有哪些人
     * @param condition
     * @return
     */
    @PostMapping("/userIdOfDeptRoles")
    public List<String> getUserIdOfDeptRoles(@RequestBody PtUserDeptMonthDTO condition) {
        return ptUserDeptMonthService.userIdOfDeptRole(condition);
    }

    /**
     * 根据条件查询 子部门权限
     *
     * @param condition 条件
     * @return com.h3c.board.model.Result
     * @author h24002
     * @date 2022-10-27
     */
    @PostMapping("/selectChild")
    public Result<Object> selectChild(@RequestBody PtUserDeptMonthDTO condition) {
        Assert.notNull(condition, CommonUtil.errorMsg("空值传入"));
        List<PtUserDeptMonthVO> voList =deptMonthMapper.selectChildDeptMonth(condition);
        return new Result(true, StatusCodeEnum.SEARCH_SUCCESS, voList);
    }



    /**
     * 执行作业--定时处理人力预算任务
     *
     * @return com.h3c.board.model.Result
     * @author h24002
     * @date 2022-10-27
     */
    @GetMapping("/executeHrBudgetJob")
    public Result<Object> executeHrBudgetJob(@RequestParam(value = "date") String date) throws ParseException {
        Date dateParse = DateUtils.dateParse(date, "yyyy-MM-dd");
        resetHrBudgetHandler.executeJob(dateParse);
        return new Result(true, StatusCodeEnum.NORMAL);
    }

    /**
     * 执行作业--定时处理人力动态看板任务
     *
     * @return com.h3c.board.model.Result
     * @author h24002
     * @date 2022-10-27
     */
    @GetMapping("/executeDynamicBoardJob")
    public Result<Object> executeDynamicBoardJob(@RequestParam(value = "date") String date) throws ParseException {
        Date dateParse = DateUtils.dateParse(date, "yyyy-MM-dd");
        resetDynamicBoardHandler.executeJob(dateParse);
        return new Result(true, StatusCodeEnum.NORMAL);
    }

    /**
     * 执行作业--定时处理人力动态看板任务
     *
     * @return com.h3c.board.model.Result
     * @author h24002
     * @date 2022-10-27
     */
    @GetMapping("/executeHrLeaderJob")
    public Result<Object> executeHrLeaderJob(@RequestParam(value = "date") String date) throws ParseException {
        Date dateParse = DateUtils.dateParse(date, "yyyy-MM-dd");
        resetHrLeaderHandler.executeJob(dateParse);
        return new Result(true, StatusCodeEnum.NORMAL);
    }

}
